package paulscode.sound;

import java.net.URL;
import javax.sound.sampled.AudioFormat;

/**
 * The ICodec interface provides a common interface for SoundSystem to use for
 * accessing external codec libraries. <br>
 * <br>
 * <b><i> SoundSystem License:</b></i><br>
 * <b><br>
 * You are free to use this library for any purpose, commercial or otherwise.
 * You may modify this library or source code, and distribute it any way you
 * like, provided the following conditions are met: <br>
 * 1) You may not falsely claim to be the author of this library or any
 * unmodified portion of it. <br>
 * 2) You may not copyright this library or a modified version of it and then
 * sue me for copyright infringement. <br>
 * 3) If you modify the source code, you must clearly document the changes made
 * before redistributing the modified source code, so other users know it is not
 * the original code. <br>
 * 4) You are not required to give me credit for this library in any derived
 * work, but if you do, you must also mention my website:
 * http://www.paulscode.com <br>
 * 5) I the author will not be responsible for any damages (physical, financial,
 * or otherwise) caused by the use if this library or any part of it. <br>
 * 6) I the author do not guarantee, warrant, or make any representations,
 * either expressed or implied, regarding the use of this library or any part of
 * it. <br>
 * <br>
 * Author: Paul Lamb <br>
 * http://www.paulscode.com </b>
 */
public interface ICodec {
	/**
	 * Should tell derived classes when they may need to reverse the byte order
	 * of the data before returning it in the read() and readAll() methods. The
	 * reason for the reversBytOrder method is because some external codec
	 * libraries produce audio data in a format that some external audio
	 * libraries require to be reversed. Derivatives of the Library and Source
	 * classes for audio libraries which require this type of data to be
	 * reversed should call the reverseByteOrder() method for all instances of
	 * ICodec that they use. Derivatives of the ICodec interface for codec
	 * libraries which which produce this type of data should use the
	 * reverseByteOrder() method to know when the data needs to be reversed
	 * before returning it in the read() and readAll() methods. If a particular
	 * codec library does not produce this type of data, its derived ICodec
	 * class may disregard any calls to the reverseByteOrder() method.
	 * 
	 * @param b
	 *            True if the calling audio library requires byte-reversal by
	 *            some codec libraries.
	 */
	public void reverseByteOrder(boolean b);

	/**
	 * Should make any preperations required before reading from the audio
	 * stream. If another stream is already opened, it should be closed and a
	 * new audio stream opened in its place. This method is used internally by
	 * SoundSystem not only to initialize a stream, but also to rewind streams
	 * and to switch stream sources on the fly.
	 * 
	 * @return False if an error occurred or if end of stream was reached.
	 */
	public boolean initialize(URL url);

	/**
	 * Should return false if the stream is busy initializing. To prevent bad
	 * data from being returned by this method, derived classes should
	 * internally synchronize with any elements used by both the initialized()
	 * and initialize() methods.
	 * 
	 * @return True if steam is initialized.
	 */
	public boolean initialized();

	/**
	 * Should read in one stream buffer worth of audio data. See
	 * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more
	 * information about accessing and changing default settings.
	 * 
	 * @return The audio data wrapped into a SoundBuffer context.
	 */
	public SoundBuffer read();

	/**
	 * Should read in all the audio data from the stream (up to the default
	 * "maximum file size". See {@link paulscode.sound.SoundSystemConfig
	 * SoundSystemConfig} for more information about accessing and changing
	 * default settings.
	 * 
	 * @return the audio data wrapped into a SoundBuffer context.
	 */
	public SoundBuffer readAll();

	/**
	 * Should return false if there is still more data available to be read in.
	 * To prevent bad data from being returned by this method, derived classes
	 * should internally synchronize with any elements used in both the
	 * endOfStream() and the read() or readAll() methods.
	 * 
	 * @return True if end of stream was reached.
	 */
	public boolean endOfStream();

	/**
	 * Should close any open streams and remove references to all instantiated
	 * objects.
	 */
	public void cleanup();

	/**
	 * Should return the audio format of the data being returned by the read()
	 * and readAll() methods.
	 * 
	 * @return Information wrapped into an AudioFormat context.
	 */
	public AudioFormat getAudioFormat();
}
